/*
*  Copyright (c) 2006-2020, Chukie
*  
*  SPDX-License-Identifier: Apache-2.0
*  
*  @file     : cellular_def.h
*  
*  @brief    : 
*  Website   : https://gitee.com/open-embedded
*  
*  
*  Change Logs:
*  Date           Author          Notes
*  2020-06-22     zhaocj       The first version
*/
/* Define to prevent recursive inclusion ------------------------------------*/
#ifndef __CELLULAR_DEF_H__
#define __CELLULAR_DEF_H__
/* Includes -----------------------------------------------------------------*/
#include <rtthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <cmsis_compiler.h>
#include <rtdevice.h>
#include <at_client.h>

#ifdef CELLULAR_USING_CMUX
#include <cmux.h>
#endif /*CELLULAR_USING_CMUX*/
#ifdef __cplusplus
extern "C"
{
#endif /*__cplusplus*/

#if RT_LWIP_TCPTHREAD_STACKSIZE < 4096
#error "TCPIP thread stack too small, please increase to 4096 bytes!"
#endif
/* Exported types -----------------------------------------------------------*/
/**access technology of the serving cell, reference to 3GPP TS 27.007 V16.6.0 (2020-09) P60 **/
typedef enum {
    NETWORK_ACT_GSM = 0,
    NETWORK_ACT_GSM_COMPACT = 1,
    NETWORK_ACT_UTRAN = 2,  //3G
    NETWORK_ACT_EGPRS = 3, //2G
    NETWORK_ACT_HSDPA = 4,
    NETWORK_ACT_HSUPA = 5,
    NETWORK_ACT_HSPA = 6,
    NETWORK_ACT_LTE = 7,//LTE
    NETWORK_ACT_EC_GSM_IOT = 8,
    NETWORK_ACT_CAT_NB = 9,
    NETWORK_ACT_5GCN = 10, /*connected to a 5GCN  (not applicable)*/
    NETWORK_ACT_5GNR = 11, //NR connected to a 5GCN (not applicable)
    NETWORK_ACT_NG_RAN = 12, //NG-RAN (not applicable)
    NETWORK_ACT_LTE_NR = 13, //E-UTRA-NR(LTE-NR) dual connectivity
    NETWORK_ACT_CDMA = 100,
    UNKNOWN
} network_act_t;

/*注册状态,参考 3GPP TS 27.007 V16.6.0 (2020-09) P278*/
typedef enum {
    /*not registered, MT is not currently searching an operator to register to*/
    REGISTER_STATE_UNREGISTERED = 0,
    /*registered, home network*/
    REGISTER_STATE_REGISTERED_HOME = 1,
    /*not registered, but MT is currently trying to attach or searching an operator to register to*/
    REGISTER_STATE_SEARCHING = 2,
    /*registration denied*/
    REGISTER_STATE_DENIED = 3,
    /*unknown (e.g. out of E-UTRAN coverage)*/
    REGISTER_STATE_UNKNOWN = 4,
    /*registered, roaming*/
    REGISTER_STATE_REGISTERED_ROAM = 5,
    REGISTER_STATE_STATE_MAX
    /*6 registered for "SMS only", home network (not applicable)*/
    /*7 registered for "SMS only", roaming (not applicable)*/
    /*8 attached for emergency bearer services only*/
    /*9 registered for "CSFB not preferred", home network (not applicable)*/
    /*10	registered for "CSFB not preferred", roaming (not applicable)*/
    /*11	attached for access to RLOS (applicable only when <AcT> indicates E-UTRAN)*/
} register_state_t;
/**Radio Access technology band**/
typedef enum{
    /*CDMA BAND*/
    CDMA_BAND_800 = 800,
    /*EVDO band*/
    EVDO_BAND_800 = 30800,
    /*GSM band*/
    GSM_BAND_450 =  450,
    GSM_BAND_480 =  480,
    GSM_BAND_750 =  750,
    GSM_BAND_850 =  850,
    GSM_BAND_900 =  900,
    GSM_BAND_1800 = 1800,
    GSM_BAND_1900 = 1900,
    /*WCDMA band*/
    WCDMA_BAND_850 = 30850,
    WCDMA_BAND_900 = 30900,
    WCDMA_BAND_1500 = 31500,
    WCDMA_BAND_1700 = 31700,
    WCDMA_BAND_1800 = 31800,
    WCDMA_BAND_1900 = 31900,
    WCDMA_BAND_2000 = 32000,
    WCDMA_BAND_2100 = 32100,
    WCDMA_BAND_2600 = 32600,
    /*TD-SCDMA band*/
    TDSCDMA_BAND_34 = 30034,
    TDSCDMA_BAND_39 = 30039,
    /*FDD LTE band*/
    LTE_BAND_1 = 40001,
    LTE_BAND_2 = 40002,
    LTE_BAND_3 = 40003,
    LTE_BAND_4 = 40004,
    LTE_BAND_5 = 40005,
    LTE_BAND_7 = 40007,
    LTE_BAND_8 = 40008,
    LTE_BAND_12 = 40012,
    LTE_BAND_13 = 40013,
    LTE_BAND_18 = 40018,
    LTE_BAND_19 = 40018,
    LTE_BAND_20 = 40020,
    LTE_BAND_25 = 40025,
    LTE_BAND_26 = 40026,
    LTE_BAND_27 = 40027,
    LTE_BAND_28 = 40028,
    LTE_BAND_66 = 40066,
    LTE_BAND_71 = 40071,
    LTE_BAND_85 = 40085,
    /*TDD LTE band*/
    LTE_BAND_38 = 40038,
    LTE_BAND_39 = 40039,
    LTE_BAND_40 = 40040,
    LTE_BAND_41 = 40041,
    UNKNOWN_BAND =  0xFFFF
}network_act_band_t;

#define TDSCDMA_BAND_A      TDSCDMA_BAND_34
#define TDSCDMA_BAND_F      TDSCDMA_BAND_39
/*模组状态*/
typedef enum {
    MODULE_OFF = (0),
    MODULE_RESETING,
    MODULE_ON,
    MODULE_PPP,
} module_state_t;

/*模组控制命令*/
typedef enum{
    /*模组开机*/
    CELLULAR_CMD_POWER = 0,
    /*模组初始化*/
    CELLULAR_CMD_INIT,
    /*检测SIM卡*/
    CELLULAR_CMD_CHECK_SIM,
    /*配置拨号参数*/
    CELLULAR_CMD_SETUP,
    /*检查网络*/
    CELLULAR_CMD_CHECK_NETWORK,
    /*数据模式*/
    CELLULAR_CMD_DATA_MODE,
    /*开关射频*/
    CELLULAR_CMD_SWITCH_RF,
    /*切换SIM卡*/
    CELLULAR_CMD_SWITCH_SIM,
    /*休眠控制*/
    CELLULAR_CMD_SLEEP_CTRL,
    /*挂断电话*/
    CELLULAR_CMD_HANGUP_CALL,
    /*复位模组*/
    CELLULAR_CMD_RESET,
    CELLULAR_CMD_MAX,
}cellular_cmd_t;

/* 配置相关***********************************************************/
typedef enum{
    NETWORK_MODE_AUTO      = 0,
    NETWORK_MODE_4G_ONLY   = 1,
    NETWORK_MODE_3G_UMTS   = 2,
    NETWORK_MODE_2G_GSM    = 3,
    NETWORK_MODE_GSM_UMTS  = 4,
    NETWORK_MODE_CAT_M1    = 5,
    NETWORK_MODE_CAT_NB    = 6,
    NETWORK_MODE_3G_HDR    = 7,
    NETWORK_MODE_2G_CDMA   = 8,
    NETWORK_MODE_CDMA_HDR  = 9
}network_mode_t;

typedef enum
{
    CELLULAR_PORT_TYPE_PPP = 0,
    CELLULAR_PORT_TYPE_AT,
} cellular_port_type_t;

typedef enum
{
    CELLULAR_OK = RT_EOK,           //success
    CELLULAR_INPROG = -RT_EBUSY,    //in progress
    CELLULAR_TIMEOUT = -RT_ETIMEOUT, //timeout
    CELLULAR_ERROR = -RT_ERROR
}cellular_err_t;
/* Exported constants -------------------------------------------------------*/
/* Exported macro -----------------------------------------------------------*/
#define MODULE_IMEI_SIZE                16
#define MODULE_VERSION_SIZE             64
#define SIM_IMSI_SIZE                   16
#define SIM_ICCID_SIZE                  20
#define SIM_NUMBER_SIZE                 32
#define NETWORK_INFO_SIZE               32
#define OPERATOR_INFO_SIZE              32

#ifdef CELLULAR_USING_DUAL_SIM
#define CELLULAR_SUPOORT_MAX_SIM_NUM    2
#else
#define CELLULAR_SUPOORT_MAX_SIM_NUM    1
#endif /*CELLULAR_USING_DUAL_SIM*/

#define CELLULAR_RING_IND_PHONE         0
#define CELLULAR_RING_IND_SMS           1

#define CELLULAR_PPP_EVENT_CLOSE_REQ    (1<<4)
#define CELLULAR_PPP_EVENT_NET_UP       (1<<5)
#define CELLULAR_PPP_EVENT_NET_DOWN     (1<<6)
#define CELLULAR_PPP_EVENT_CLOSED       (1<<7)

#define CELLULAR_PPP_MAX_DIAL_NUMBER_LEN 64
#define CELLULAR_PPP_MAX_APN_LEN        128
#define CELLULAR_PPP_MAX_USERNAME_LEN   128
#define CELLULAR_PPP_MAX_PASWORD_LEN    128

#define CELLULAR_CMUX_CMD                "AT+CMUX=0,0,5,256,10,3,30,10,2"
/* Exported functions -------------------------------------------------------*/

/**
 * @brief sleep seconds
 *
 */
#ifndef sleep
#define sleep(s)    rt_thread_mdelay((s)*1000)
#endif /*sleep*/
/**
 * @brief sleep millseconds
 *
 */
#ifndef sleepm
#define sleepm(ms)  rt_thread_mdelay(ms)
#endif /*sleepm*/
/**
 * @brief get system now time in seconds
 * @Note: maybe wrapp
 * @return current system time in seconds
 */
#ifndef uptime
#define uptime()    ((rt_tick_get()) / RT_TICK_PER_SECOND)
#endif /*uptime*/

/**
 * @brief get system now time in millseconds
 * @Note: maybe wrapp
 * @return system now time in millseconds
 */
#ifndef uptimem
#define uptimem()   rt_tick_get_millisecond()
#endif /*uptimem*/


#ifndef time_after
#define time_after(a,b)         ((long)(b) - (long)(a) < 0)
#endif /*time_after*/

#ifndef time_before
#define time_before(a,b)        time_after(b,a)
#endif /*time_before*/

#ifndef time_after_eq
#define time_after_eq(a,b)      ((long)(a) - (long)(b) >= 0)
#define time_before_eq(a,b)     time_after_eq(b,a)
#define time_in_range(a,b,c)    (time_after_eq(a,b) && time_before_eq(a,c))
#endif /*time_after_eq*/

/**
 * @brief hardware init
 * 
 * @return  
 */
void cellular_hw_init(void);

/**
 * @brief switch sim
 * 
 * @param idx sim index,allowed value: 0~1
 * @return  
 */
void cellular_hw_sim_switch(uint8_t idx);

/**
 * @brief Set cellular power
 * 
 * @param on    0: power-off; 1: power on
 * @return  
 */
void cellular_hw_set_power(int on);

/**
 * @brief Set cellular power key level
 * 
 * @param high 0: low level; 1: high level
 * @return  
 */
void cellular_hw_set_power_key(int high);

/**
 * @brief Set cellular reset pin level
 * 
 * @param high 0: low level; 1: high level
 * @return  
 */
void cellular_hw_set_reset_pin(int high);

/**
 * @brief Set cellular sleep control pin level
 * 
 * @param high 0: low level; 1: high level
 * @return  
 */
void cellular_hw_set_sleep_ctrl(int high);

/**
 * @brief read cellular sleep status pin 
 * 
 * @return  
 */
int cellular_hw_get_sleep_status(void);

/**
 * @brief save cellular state to non-volatile
 * 
 * @param state reference to module_state_t
 * @return  
 */
void cellular_save_state_to_nv(module_state_t state);

/**
 * @brief read cellular state from non-volatile
 * 
 * @return  
 */
module_state_t cellular_read_state_from_nv(void);

/**
 * @brief save used sim index to non-volatile
 * 
 * @param index sim index 
 * @return  
 */
void cellular_save_used_sim_to_nv(int index);

/**
 * @brief read used sim index from non-volatile
 * 
 * @return  
 */
module_state_t cellular_read_used_sim_from_nv(void);

#ifdef __cplusplus
{
#endif /*__cplusplus*/
#endif /*__CELLULAR_DEF_H__*/
/* End of file****************************************************************/

